package org.luxor.cloud.authentication.component.captcha;

import com.octo.captcha.engine.CaptchaEngine;
import com.octo.captcha.service.CaptchaServiceException;
import com.octo.captcha.service.captchastore.CaptchaStore;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import com.octo.captcha.service.image.ImageCaptchaService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Locale;

/**
 * 验证码服务
 *
 * @author Mr.Yan  @date: 2021/1/6
 */
public class CaptchaService {
    private static final Logger logger = LoggerFactory.getLogger(CaptchaService.class);

    private ImageCaptchaService imageCaptchaService;

    private CaptchaStore captchaStore;

    public CaptchaService(CaptchaStore captchaStore, CaptchaEngine captchaEngine) {
        this.captchaStore = captchaStore;
        this.imageCaptchaService = new DefaultManageableImageCaptchaService(
                captchaStore,
                captchaEngine,
                8,
                1000,
                750);
    }

    /**
     * 获取验证码图片
     *
     * @param sessionId 会话ID
     * @return 图片字节流
     */
    public byte[] getCaptchaImage(String sessionId) {
        try {
            captchaStore.removeCaptcha(sessionId);
            BufferedImage srcImage = imageCaptchaService.getImageChallengeForID(sessionId, Locale.SIMPLIFIED_CHINESE);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(srcImage, "gif", out);
            return out.toByteArray();
        } catch (IOException e) {
            logger.error("获取验证码图片失败.", e);
            return new byte[]{};
        }
    }

    /**
     * 检查验证码的合法性
     *
     * @param sessionId   会话ID
     * @param captchaCode 验证码
     * @return 验证结果，true 代表通过；false代表不通过
     */
    public boolean verify(String sessionId, String captchaCode) {
        try {
            return imageCaptchaService.validateResponseForID(sessionId, captchaCode).booleanValue();
        } catch (CaptchaServiceException e) {
            logger.error("检查验证码失败.", e);
            return false;
        }
    }

}
